package com.centerm.common.util;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.filechooser.FileSystemView;

import org.apache.commons.codec.digest.DigestUtils;

public class FileUtil {
	/**
	 * 删除指定路径的文件
	 * @return boolean
	 * */
	public static boolean deleteFile(String filePath) {
		File file = new File(filePath);
		return file.delete();
	}
	
	/**
	 * 获取指定目录下的所有文件夹和文件的名字
	 * @param baseFilePath:String 待查询的根目录路径
	 * @param isDirectoryIncluded:boolean 是否包含目录
	 * @return 指定目录的包含文件文件夹的名字
	 * @author Fly
	 * */
	public static List<String> getFileNames(String baseFilePath,boolean isDirectoryIncluded){
		List<String> fileNames = new ArrayList<String>();
		File baseFile = new File(baseFilePath);
		File[] files = baseFile.listFiles();
		if(files!=null){
			for(File file:files){
				if(file.isDirectory()){
					if(isDirectoryIncluded == true){
						fileNames.add(file.getName());
					}
					fileNames.addAll(getFileNames(file.getAbsolutePath(),false));
				} else {
					fileNames.add(file.getName());
				}
			}
		}
		return fileNames;
	}
	
	/**
	 * 获取指定目录下的所有文件夹和文件的全路径 
	 * @param baseFilePath:String 待查询的根目录路径
	 * @param isDirectoryIncluded:boolean 是否包含目录路径
	 * @return 指定目录的包含文件文件夹的路径
	 * @author Fly
	 * */
	public static List<String> getFilePaths(String baseFilePath,boolean isDirectoryIncluded){
		List<String> filePaths = new ArrayList<String>();
		File baseFile = new File(baseFilePath);
		File[] files = baseFile.listFiles();
		if(files!=null){
			for(File file:files){
				if(file.isDirectory()){
					if(isDirectoryIncluded == true){
						filePaths.add(file.getAbsolutePath());
					}
					filePaths.addAll(getFilePaths(file.getAbsolutePath(),isDirectoryIncluded));
				} else {
					filePaths.add(file.getAbsolutePath());
				}
			}
		}
		return filePaths;
	}
	
	/**
	 * 获取文件的名字
	 * @param filePath:String 文件全路径
	 * @return 获取文件的名字
	 * @author Fly
	 * */
	public static String getFileName(String filePath){
		String[] fileDirs = filePath.split("\\" + File.separator);
		String fileName = fileDirs[fileDirs.length - 1];
		
		return fileName;
	}
	
	/**
	 * 获取文件的名字(正斜杠/)
	 * @param filePath:String 文件全路径
	 * @return 获取文件的名字
	 * @author Fly
	 * */
	public static String getReverseFileName(String filePath){
		String[] fileDirs = filePath.split("/");
		String fileName = fileDirs[fileDirs.length - 1];
		
		return fileName;
	}
	
	/**
	 * 获取文件的大小
	 * @param filePath:String 文件全路径
	 * @return 获取文件的大小
	 * @author Fly
	 * */
	public static long getFileSize(String filePath){
		File file = new File(filePath);
		return file.length();
	}
	
	/**
	 * 获取文件的最后修改时间
	 * @param filePath:String 文件全路径
	 * @return 获取文件的最后修改时间
	 * @author Fly
	 * */
	public static String getFileTime(String filePath){
		File file = new File(filePath);
		return DateUtil.getDateStringByMillis(file.lastModified());
	}
	
	
	
	//获取指定文件名的文件后缀
	public static String getSuffixByFileName(String fileName){
		String[] fileParts = fileName.split("\\.");
		return fileParts[fileParts.length - 1];
	}
	
	//获取应用图标存放到指定目录下
	public static void getFileImage(File tmpFile,String tmpIconPath){
		ImageIcon icon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon(tmpFile);
		BufferedImage savedImage = new BufferedImage(icon.getIconWidth(),
				icon.getIconHeight(),
				BufferedImage.TYPE_INT_ARGB);
		savedImage.createGraphics().drawImage(icon.getImage(), 0, 0, null);
		File tmpIconFile = new File(tmpIconPath);
		try {
			if(!tmpIconFile.exists()){
				tmpIconFile.mkdirs();
				tmpIconFile.createNewFile();
			}
			ImageIO.write(savedImage, "png", tmpIconFile);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//获取应用图标存放到指定目录下
	public static void getFileBigImage(File tmpFile,String tmpIconPath){
		ImageIcon icon = new ImageIcon();
		 try {
			   sun.awt.shell.ShellFolder shellFolder = sun.awt.shell.ShellFolder.getShellFolder(tmpFile);
		       icon.setImage(shellFolder.getIcon(true));
		} catch (FileNotFoundException e) {
		      e.printStackTrace();
		}
		
		BufferedImage savedImage = new BufferedImage(icon.getIconWidth(),
				icon.getIconHeight(),
				BufferedImage.TYPE_INT_ARGB);
		savedImage.createGraphics().drawImage(icon.getImage(), 0, 0, null);
		File tmpIconFile = new File(tmpIconPath);
		try {
			if(!tmpIconFile.exists()){
				tmpIconFile.mkdirs();
				tmpIconFile.createNewFile();
			}
			ImageIO.write(savedImage, "png", tmpIconFile);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static File autoRename(String filePath) {
		return autoRename(0, filePath);
	}

	private static File autoRename(int count, String filePath) {
		count++;
		File file = new File(filePath);
		if (file.exists()) {
			String path = file.getAbsolutePath();
			int index = path.lastIndexOf(".");
			if (count == 1) {
				path = path.substring(0, index) + "(1)" + path.substring(index, path.length());
			} else {
				path = path.replace("(" + (count - 1) + ")", "(" + count + ")");
			}
			file = new File(path);
			return autoRename(count, file.getAbsolutePath());
		} else {
			return file;
		}
	}

	/**
	 * 删除指定目录下全部文件
	 * @param dir
	 * @return true/false
	 */
	public static boolean deleteDir(File dir, boolean isDirectoryIncluded) {
		if (dir.isDirectory()) {
			String[] children = dir.list();
			if(children!=null){
				for (int i = 0; i < children.length; i++) {
					boolean success = deleteDir(new File(dir, children[i]), isDirectoryIncluded);
					if (!success) {
						return false;
					}
				}
				if (isDirectoryIncluded) {
					return dir.delete();
				} else {
					return true;
				}
			}
			return true;
		} else {
			return dir.delete();
		}
	}

	public static String getFileStr(String filePath) {
		File file = new File(filePath);
		Long filelength = file.length(); //获取文件长度
		byte[] filecontent = new byte[filelength.intValue()];
		try {
			FileInputStream in = new FileInputStream(file);
			in.read(filecontent);
			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		String htmlStr = "";
		try {
			htmlStr = new String(filecontent, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
		return htmlStr;
	}

	public static boolean createFile(String folderPath, String fileName, String content, String postfix,
			String encoding) {
		File savePath = new File(folderPath);
		if (!savePath.exists()) {
			savePath.mkdirs();
		}
		String htmlPath = savePath.getPath() + File.separator + fileName + postfix;
		File html = new File(htmlPath);
		try {
			FileOutputStream fos = new FileOutputStream(html);
			OutputStreamWriter write = new OutputStreamWriter(fos, encoding);
			write.write(content);
			write.flush();
			write.close();
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	//判断目录是否存在，不存在则新建目录,含所有父目录
	public static boolean mkDirs(String dir) {
		try {
			File file = new File(dir);
			if(!file.exists()){
				file.mkdirs();
			}
			return file.exists();
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 计算文件的md5值
	 * 
	 * @param filepath
	 * @return
	 * @throws Exception
	 */
	public static String getFileMD5(File file) throws Exception {
		FileInputStream in = new FileInputStream(file);
		String md5 = DigestUtils.md5Hex(in);
		in.close();
		return md5.toUpperCase();
	}
	
	/**
     * 复制文件
     * @param fromFile
     * @param toFile
     * @throws IOException 
     */
    public static void copyFile(File fromFile,File toFile) throws IOException{
        FileInputStream ins = new FileInputStream(fromFile);
        FileOutputStream out = new FileOutputStream(toFile);
        byte[] b = new byte[1024];
        //int n=0;
        while(ins.read(b)!=-1){
            out.write(b, 0, b.length);
        }
        
        ins.close();
        out.close();
    }
    
	public static boolean zipFiles(List<String> filePaths, String zipFilePath) {
		byte[] buf = new byte[1024];
		int readLength = 0;
		FileOutputStream f = null;
		ZipOutputStream zos = null;
		BufferedInputStream bin = null;
		
		try {
			f = new FileOutputStream(zipFilePath);
			// 创建压缩输出流
			zos = new ZipOutputStream(new BufferedOutputStream(
					f));
			// 设置Zip文件注释
			//zos.setEncoding("gbk");
			//zos.setComment("a downloading file from Centerm system by Fly");
			for (int i = 0; i < filePaths.size(); i++) {
				// 针对单个文件建立读取流
				bin = new BufferedInputStream(
						new FileInputStream(filePaths.get(i)));
				// ZipEntry ZIP 文件条目
				// putNextEntry 写入新条目，并定位到新条目开始处
				String fileName = new File(filePaths.get(i)).getName();
				zos.putNextEntry(new ZipEntry(filePaths.get(i).substring(filePaths.get(i).length()) + File.separator + fileName));
				
				while ((readLength = bin.read(buf, 0, 1024)) != -1) {
					zos.write(buf,0,readLength);
				}
				bin.close();
				zos.flush();
			}
			zos.close();
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} finally {
			try {
				if(f!=null){
					f.close();
					f=null;
				}
				if(bin!=null) {
					bin.close();
					bin =null;
				}
				if(zos!=null) {
					zos.close();
					zos =null;
				}
			} catch (Exception e2) {
				e2.printStackTrace();
				return false;
			}
		}
		return true;
	}
}
